package com.andox.fn.inf.rpc.rest.serializer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import org.apache.commons.codec.binary.Base64;

import com.andox.fn.inf.rpc.rest.extension.Extension;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;


/**   
 * @ClassName:   HessianSerializer   
 * @Description: TODO  
 * @author:      Andox
 * @date:        2019年7月31日 下午3:32:44   
 *     
 */
@Extension("hessian2")
public class Hessian2Serializer implements Serializer {
	public static final Hessian2Serializer DEFAULT_INSTANCE = new Hessian2Serializer();
	
	public static void main(String[] args) {
		DEFAULT_INSTANCE.unserializeFromString(DEFAULT_INSTANCE.serializeAsString("abc"), String.class);
	}
	
	@Override
	public byte[] serialize(Object object) {
		if (object == null) 
			return new byte[] {};
		
		try {
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			Hessian2Output ho = new Hessian2Output(os);
			ho.writeObject(object);
			ho.getBytesOutputStream().flush();
			ho.completeMessage(); 
			ho.close();
			byte[] bytes = os.toByteArray();
			return bytes;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public String serializeAsString(Object object) {
		byte[] bytes = this.serialize(object);
		return Base64.encodeBase64String(bytes);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T unserialize(byte[] source, Class<T> clazz) {
		if (source == null || source.length == 0) 
			return null;
		
		try {
			ByteArrayInputStream is = new ByteArrayInputStream(source);
			Hessian2Input hi = new Hessian2Input(is);
			Object person = hi.readObject();
			hi.close();
			return (T)person;
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public <T> T unserializeFromString(String source, Class<T> clazz) {
		if (source == null || source.length() == 0)
			return null;
		
		byte[] bytes = Base64.decodeBase64(source);
		return this.unserialize(bytes, clazz);
	}
}
